﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Web;
using System.Globalization;
using SecureCookie.Implementation.Protocol;

namespace SecureCookie.Implementation.UnitTest.ProtocolTests
{
    [TestClass]
    public class Single_value_persistent_scenarios
    {
        private ServerSideData MyServer { get; set; }
        private IRequestState RequestState { get; set; }

        [TestInitialize]
        public void Test_Initialize()
        {
            MyServer = new ServerSideData("MySecretKey", TimeSpan.FromSeconds(10), "Woepy");
            RequestState = new Stub.StubRequestState();
        }

        [TestMethod]
        public void Test_SecureCookie_from_single_value_persistent_cookie()
        {
            var myCookie = new HttpCookie("MyCookie", "MyValue");
            myCookie.Expires = DateTime.Now.AddDays(1);
            var securedCookie = SecureCookieProtocol.MakeSecure(myCookie, MyServer, RequestState);

            Assert.IsTrue(securedCookie.Values.Count > 2);
            Assert.IsFalse(string.IsNullOrEmpty(securedCookie.Values[0]));
            //Server validates:
            Assert.AreEqual(ValidationResult.Valid, SecureCookieProtocol.Validate(securedCookie, MyServer, RequestState));
        }

        [TestMethod]
        public void Test_SecureCookie_from_single_value_but_expired()
        {
            var myCookie = new HttpCookie("MyCookie", "MyValue");
            myCookie.Expires = DateTime.Now.AddDays(-1);
            var securedCookie = SecureCookieProtocol.MakeSecure(myCookie, MyServer, RequestState);
            // Server validates:
            Assert.AreEqual(ValidationResult.InvalidIsExpired, SecureCookieProtocol.Validate(securedCookie, MyServer, RequestState));
        }

        [TestMethod]
        public void Test_SecureCookie_from_single_value_but_user_tried_to_change_expiration()
        {
            var myCookie = new HttpCookie("MyCookie", "MyValue");
            myCookie.Expires = DateTime.Now.AddDays(1);
            var securedCookie = SecureCookieProtocol.MakeSecure(myCookie, MyServer, RequestState);

            // User changes:
            securedCookie.SetExpirationPart(DateTime.Now.AddDays(20));
            // Server validates:
            Assert.AreEqual(ValidationResult.InvalidHashingCode, SecureCookieProtocol.Validate(securedCookie, MyServer, RequestState));
        }

        [TestMethod]
        public void Test_SecureCookie_from_single_value_but_user_tried_to_change_data()
        {
            var myCookie = new HttpCookie("MyCookie", "MyValue");
            myCookie.Expires = DateTime.Now.AddDays(1);
            var securedCookie = SecureCookieProtocol.MakeSecure(myCookie, MyServer, RequestState);

            // User changes:
            securedCookie.SetDataPart("My new values");
            // Server validates:
            Assert.AreEqual(ValidationResult.InvalidHashingCode, SecureCookieProtocol.Validate(securedCookie, MyServer, RequestState));
        }

        [TestMethod]
        public void Test_SecureCookie_from_single_value_but_user_tried_to_change_hash()
        {
            var myCookie = new HttpCookie("MyCookie", "MyValue");
            myCookie.Expires = DateTime.Now.AddDays(1);
            var securedCookie = SecureCookieProtocol.MakeSecure(myCookie, MyServer, RequestState);

            // User changes:
            securedCookie.SetHashPart("My new hash");
            // Server validates:
            Assert.AreEqual(ValidationResult.InvalidHashingCode, SecureCookieProtocol.Validate(securedCookie, MyServer, RequestState));
        }

        [TestMethod]
        public void Test_SecureCookie_but_user_tries_attack_from_another_client()
        {
            var myCookie = new HttpCookie("MyCookie", "MyValue");
            myCookie.Expires = DateTime.Now.AddDays(1);
            var securedCookie = SecureCookieProtocol.MakeSecure(myCookie, MyServer, RequestState);

            MyServer.ClientUniqueValue = "changed";
            // Server validates:
            Assert.AreEqual(ValidationResult.InvalidHashingCode, SecureCookieProtocol.Validate(securedCookie, MyServer, RequestState));
        }
    }
}
